# GDIR define
GDIR=../../../../


# MACIPATH define
MACIPATH=$(GDIR)/MaCI


# External includes
include $(GDIR)/GIMI/Makefile.gimi
include $(MACIPATH)/interfaces/MaCI-interfaces.Makefile


# params
CC=gcc
CXX=g++
EXTRADEFS=-DLINUX_OS -DGIMI_NO_DATATYPE_INCLUDES $(CE)
MACIPATH=$(GDIR)/MaCI
UTILSPATH=$(GDIR)/utils
BUSPATH=$(MACIPATH)/bus
DRIVERPATH=$(MACIPATH)/drivers
MACIINTERFACEPATH=$(MACIPATH)/interfaces
INCLUDES=-I$(UTILSPATH) $(INCGIMI) \
	$(MACI_INCLUDE_PATHS) \
        $(MACI_EXT_INCLUDE_PATHS)
WFLAGSC=-Wall -Wunused -Wshadow
WFLAGSCPP=-Wall -Wunused -Wshadow -Weffc++
WFLAGSDCPP=
CFLAGS=-O0 -g3 $(WFLAGSC) $(INCLUDES) $(EXTRADEFS) -fPIC
CPPFLAGS=-O0 -g3 $(WFLAGSCPP) $(INCLUDES) $(EXTRADEFS) -fPIC
DCPPFLAGS=-O0 -g3 $(WFLAGSDCPP) $(INCLUDES) $(EXTRADEFS) -fPIC
LD=g++
LDFLAGS=-ljpeg
LIBS=-lrt -lpthread -lcurses $(LIBSGIMI) `libpng-config --libs`

SRCSC=$(CGIMI)
SRCSCPP=$(CPPGIMI)
VPATH=
PYLIB=`python-config --includes`

# Construct final lists of CPP and C objects
OBJSC=$(SRCSC:.c=.o)
OBJSCPP=$(SRCSCPP:.cpp=.opp)
MACIOBJSCPP=$(MACISRCSCPP:.cpp=.opp)

# Define COMPILE and LINK commands
COMPILEC=$(CC) $(CFLAGS) -c
COMPILECPP=$(CXX) $(CPPFLAGS) -c
COMPILEDCPP=$(CXX) $(DCPPFLAGS) -c
LINK=$(LD) $(LDFLAGS) 

.PHONY: all

# Define here all interfaces which have a Python wrapper implemented
TARGETS=CoordinateDriveClient \
	CoordinateDriveServer \
	RangingClient \
	SpeedCtrlClient \
	JointGroupCtrlClient \
	PositionClient \
	PositionServer \
	ImageClient \
	ImageServer \
	IOClient \
	IOServer \
	TaskCtrlClient \
	TaskCtrlServer \
	MapClient \
	MapServer


# All rule compiles all per default
all:	$(TARGETS)

###############################################
###############################################

####### CoordinateDrive Interface Python Wrap ##############
COORDINATEDRIVECLIENT_OBJECTS=$(OBJSC) $(OBJSCPP) \
	$(MACI_EXT_SRC_CPP:.cpp=.opp) \
	$(MACI_BASE_SRC_CPP:.cpp=.opp) \
	$(MACI_INTERFACE_COORDINATEDRIVE_COMMON_CPP:.cpp=.opp) \
	$(MACI_INTERFACE_COORDINATEDRIVECLIENT_CPP:.cpp=.opp) \
	$(MACI_INTERFACE_COORDINATEDRIVESERVER_CPP:.cpp=.opp)
CoordinateDriveClient: lib $(COORDINATEDRIVECLIENT_OBJECTS)
	swig $(INCLUDES) -c++ -python -o CoordinateDriveClient_Python.cpp \
		$(MACIINTERFACEPATH)/CoordinateDrive/CoordinateDriveClient.i
		$(COMPILECPP) $(PYLIB) \
		CoordinateDriveClient_Python.cpp -o CoordinateDriveClient_Python.opp
	$(LINK) -shared -fPIC -o _CoordinateDriveClient.so \
		$(COORDINATEDRIVECLIENT_OBJECTS) $(MACIOBJSCPP)\
		CoordinateDriveClient_Python.opp \
		$(LIBS)
	mv _CoordinateDriveClient.so CoordinateDriveClient.py ./lib

CoordinateDriveServer: lib $(COORDINATEDRIVECLIENT_OBJECTS)
	swig $(INCLUDES) -c++ -python -o CoordinateDriveServer_Python.cpp \
		$(MACIINTERFACEPATH)/CoordinateDrive/CoordinateDriveServer.i
		$(COMPILECPP) $(PYLIB) \
		CoordinateDriveServer_Python.cpp -o CoordinateDriveServer_Python.opp
	$(LINK) -shared -fPIC -o _CoordinateDriveServer.so \
		$(COORDINATEDRIVECLIENT_OBJECTS) $(MACIOBJSCPP)\
		CoordinateDriveServer_Python.opp \
		$(LIBS)
	mv _CoordinateDriveServer.so CoordinateDriveServer.py ./lib
###################################################

####### IO Interface Python Wrap ##############
IOCLIENT_OBJECTS=$(OBJSC) $(OBJSCPP) \
	$(MACI_EXT_SRC_CPP:.cpp=.opp) \
	$(MACI_BASE_SRC_CPP:.cpp=.opp) \
	$(MACI_INTERFACE_IO_COMMON_CPP:.cpp=.opp) \
	$(MACI_INTERFACE_IOCLIENT_CPP:.cpp=.opp) \
	$(MACI_INTERFACE_IOSERVER_CPP:.cpp=.opp)
IOClient: lib $(IOCLIENT_OBJECTS)
	swig $(INCLUDES) -c++ -python -o IOClient_Python.cpp \
		$(MACIINTERFACEPATH)/IO/IOClient.i
		$(COMPILECPP) $(PYLIB) \
		IOClient_Python.cpp -o IOClient_Python.opp
	$(LINK) -shared -fPIC -o _IOClient.so \
		$(IOCLIENT_OBJECTS) $(MACIOBJSCPP)\
		IOClient_Python.opp \
		$(LIBS)
	mv _IOClient.so IOClient.py ./lib

IOServer: lib $(IOCLIENT_OBJECTS)
	swig $(INCLUDES) -c++ -python -o IOServer_Python.cpp \
		$(MACIINTERFACEPATH)/IO/IOServer.i
		$(COMPILECPP) $(PYLIB) \
		IOServer_Python.cpp -o IOServer_Python.opp
	$(LINK) -shared -fPIC -o _IOServer.so \
		$(IOCLIENT_OBJECTS) $(MACIOBJSCPP)\
		IOServer_Python.opp \
		$(LIBS)
	mv _IOServer.so IOServer.py ./lib
###################################################

####### Ranging Interface Python Wrap ##########################
RANGINGCLIENT_OBJECTS=$(OBJSC) $(OBJSCPP) \
		        $(MACI_EXT_SRC_CPP:.cpp=.opp) \
	                $(MACI_BASE_SRC_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_RANGING_COMMON_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_RANGINGCLIENT_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_RANGINGSERVER_CPP:.cpp=.opp)
RangingClient: lib $(RANGINGCLIENT_OBJECTS)
	swig $(INCLUDES) -c++ -python -o RangingClient_Python.cpp \
		$(MACIINTERFACEPATH)/Ranging/RangingClient.i
	$(COMPILECPP) $(PYLIB) \
		RangingClient_Python.cpp -o RangingClient_Python.opp
	$(LINK) -shared -fPIC -o _RangingClient.so \
		$(RANGINGCLIENT_OBJECTS) $(MACIOBJSCPP) \
		RangingClient_Python.opp \
		$(LIBS)
	mv _RangingClient.so RangingClient.py ./lib
################################################################

####### SpeedCtrl Interface Python Wrap ##########################
SPEEDCTRLCLIENT_OBJECTS=$(OBJSC) $(OBJSCPP) \
		        $(MACI_EXT_SRC_CPP:.cpp=.opp) \
	                $(MACI_BASE_SRC_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_SPEEDCTRL_COMMON_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_SPEEDCTRLCLIENT_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_SPEEDCTRLSERVER_CPP:.cpp=.opp)
SpeedCtrlClient: lib $(SPEEDCTRLCLIENT_OBJECTS)
	swig $(INCLUDES) -c++ -python -o SpeedCtrlClient_Python.cpp \
		$(MACIINTERFACEPATH)/SpeedCtrl/SpeedCtrlClient.i
	$(COMPILECPP) $(PYLIB) \
		SpeedCtrlClient_Python.cpp -o SpeedCtrlClient_Python.opp
	$(LINK) -shared -fPIC -o _SpeedCtrlClient.so \
		$(SPEEDCTRLCLIENT_OBJECTS) $(MACIOBJSCPP) \
		SpeedCtrlClient_Python.opp \
		$(LIBS)
	mv _SpeedCtrlClient.so SpeedCtrlClient.py ./lib
################################################################

####### JointGroupCtrl Interface Python Wrap ##########################
JOINTGROUPCTRLCLIENT_OBJECTS=$(OBJSC) $(OBJSCPP) \
		        $(MACI_EXT_SRC_CPP:.cpp=.opp) \
	                $(MACI_BASE_SRC_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_JOINTGROUPCTRL_COMMON_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_JOINTGROUPCTRLCLIENT_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_JOINTGROUPCTRLSERVER_CPP:.cpp=.opp)
JointGroupCtrlClient: lib $(JOINTGROUPCTRLCLIENT_OBJECTS)
	swig $(INCLUDES) -c++ -python -o JointGroupCtrlClient_Python.cpp \
		$(MACIINTERFACEPATH)/JointGroupCtrl/JointGroupCtrlClient.i
	$(COMPILECPP) $(PYLIB) \
		JointGroupCtrlClient_Python.cpp -o JointGroupCtrlClient_Python.opp
	$(LINK) -shared -fPIC -o _JointGroupCtrlClient.so \
		$(JOINTGROUPCTRLCLIENT_OBJECTS) $(MACIOBJSCPP) \
		JointGroupCtrlClient_Python.opp \
		$(LIBS)
	mv _JointGroupCtrlClient.so JointGroupCtrlClient.py ./lib
################################################################

####### Position Interface Python Wrap ##########################
POSITION_OBJECTS=$(OBJSC) $(OBJSCPP) \
		        $(MACI_EXT_SRC_CPP:.cpp=.opp) \
	                $(MACI_BASE_SRC_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_POSITION_COMMON_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_POSITIONCLIENT_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_POSITIONSERVER_CPP:.cpp=.opp)
PositionClient: lib $(POSITION_OBJECTS)
	swig $(INCLUDES) -c++ -python -o PositionClient_Python.cpp \
		$(MACIINTERFACEPATH)/Position/PositionClient.i
		$(COMPILECPP) $(PYLIB) \
		PositionClient_Python.cpp -o PositionClient_Python.opp
	$(LINK) -shared -fPIC -o _PositionClient.so \
		$(POSITION_OBJECTS) $(MACIOBJSCPP) \
		PositionClient_Python.opp \
		$(LIBS)
	mv _PositionClient.so PositionClient.py ./lib

PositionServer: lib $(POSITION_OBJECTS)
	swig $(INCLUDES) -c++ -python -o PositionServer_Python.cpp \
		$(MACIINTERFACEPATH)/Position/PositionServer.i
		$(COMPILECPP) $(PYLIB) \
		PositionServer_Python.cpp -o PositionServer_Python.opp
	$(LINK) -shared -fPIC -o _PositionServer.so \
		$(POSITION_OBJECTS) $(MACIOBJSCPP) \
		PositionServer_Python.opp \
		$(LIBS)
	mv _PositionServer.so PositionServer.py ./lib
################################################################

####### Image Interface Python Wrap ##########################
IMAGECLIENT_OBJECTS=$(OBJSC) $(OBJSCPP) \
		        $(MACI_EXT_SRC_CPP:.cpp=.opp) \
	                $(MACI_BASE_SRC_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_IMAGE_COMMON_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_IMAGECLIENT_CPP:.cpp=.opp) \
	                $(MACI_INTERFACE_IMAGESERVER_CPP:.cpp=.opp) \
	                $(GDIR)/ImageUtils/JPEGEncoder/JPEGEncoder.opp \
	                $(GDIR)/ImageUtils/JPEGDecoder/JPEGDecoder.opp \
	                $(GDIR)/ImageUtils/PNGDecoder/PNGDecoder.opp \
	                $(GDIR)/ImageUtils/PNGEncoder/PNGEncoder.opp
ImageClient: lib $(IMAGECLIENT_OBJECTS)
	swig $(INCLUDES) -c++ -python -o ImageClient_Python.cpp \
		$(MACIINTERFACEPATH)/Image/ImageClient.i
	$(COMPILECPP) $(PYLIB) \
		ImageClient_Python.cpp -o ImageClient_Python.opp
	$(LINK) -shared -fPIC -o _ImageClient.so \
		$(IMAGECLIENT_OBJECTS) $(MACIOBJSCPP) \
		ImageClient_Python.opp \
		$(LIBS)
	mv _ImageClient.so ImageClient.py ./lib

ImageServer: lib $(IMAGECLIENT_OBJECTS)
	swig $(INCLUDES) -c++ -python -o ImageServer_Python.cpp \
		$(MACIINTERFACEPATH)/Image/ImageServer.i
	$(COMPILECPP) $(PYLIB) \
		ImageServer_Python.cpp -o ImageServer_Python.opp
	$(LINK) -shared -fPIC -o _ImageServer.so \
		$(IMAGECLIENT_OBJECTS) $(MACIOBJSCPP) \
		ImageServer_Python.opp \
		$(LIBS)
	mv _ImageServer.so ImageServer.py ./lib
################################################################


####### Map Interface Python Wrap ##########################
MAPCLIENT_OBJECTS=$(OBJSC) $(OBJSCPP) \
		  $(MACI_EXT_SRC_CPP:.cpp=.opp) \
	          $(MACI_BASE_SRC_CPP:.cpp=.opp) \
	          $(MACI_INTERFACE_MAP_COMMON_CPP:.cpp=.opp) \
                  $(MACI_INTERFACE_MAPCLIENT_CPP:.cpp=.opp) \
	          $(MACI_INTERFACE_MAPSERVER_CPP:.cpp=.opp) \
		  $(MACI_INTERFACE_MAP_EXT_CPP:.cpp=.opp)
MapClient: lib $(MAPCLIENT_OBJECTS)
	swig $(INCLUDES) -c++ -python -o MapClient_Python.cpp \
		$(MACIINTERFACEPATH)/Map/MapClient.i
	$(COMPILECPP) $(PYLIB) \
		MapClient_Python.cpp -o MapClient_Python.opp
	$(LINK) -shared -fPIC -o _MapClient.so \
		$(MAPCLIENT_OBJECTS) $(MACIOBJSCPP) \
		MapClient_Python.opp \
		$(LIBS) $(MACI_INTERFACE_MAP_EXT_LIBS)
	mv _MapClient.so MapClient.py ./lib

MapServer: lib $(MAPCLIENT_OBJECTS)
	swig $(INCLUDES) -c++ -python -o MapServer_Python.cpp \
		$(MACIINTERFACEPATH)/Map/MapServer.i
	$(COMPILECPP) $(PYLIB) \
		MapServer_Python.cpp -o MapServer_Python.opp
	$(LINK) -shared -fPIC -o _MapServer.so \
		$(MAPCLIENT_OBJECTS) $(MACIOBJSCPP) \
		MapServer_Python.opp \
		$(LIBS) $(MACI_INTERFACE_MAP_EXT_LIBS)
	mv _MapServer.so MapServer.py ./lib
################################################################

####### TaskCtrl Interface Python Wrap ##########################
TASKCTRLCLIENT_OBJECTS=$(OBJSC) $(OBJSCPP) \
		  $(MACI_EXT_SRC_CPP:.cpp=.opp) \
	          $(MACI_BASE_SRC_CPP:.cpp=.opp) \
	          $(MACI_INTERFACE_TASKCTRL_COMMON_CPP:.cpp=.opp) \
                  $(MACI_INTERFACE_TASKCTRLCLIENT_CPP:.cpp=.opp) \
	          $(MACI_INTERFACE_TASKCTRLSERVER_CPP:.cpp=.opp) \
		  $(MACI_INTERFACE_TASKCTRL_EXT_CPP:.cpp=.opp)
TaskCtrlClient: lib $(TASKCTRLCLIENT_OBJECTS)
	swig $(INCLUDES) -c++ -python -o TaskCtrlClient_Python.cpp \
		$(MACIINTERFACEPATH)/TaskCtrl/TaskCtrlClient.i
	$(COMPILECPP) $(PYLIB) \
		TaskCtrlClient_Python.cpp -o TaskCtrlClient_Python.opp
	$(LINK) -shared -fPIC -o _TaskCtrlClient.so \
		$(TASKCTRLCLIENT_OBJECTS) $(MACIOBJSCPP) \
		TaskCtrlClient_Python.opp \
		$(LIBS) $(MACI_INTERFACE_TASKCTRL_EXT_LIBS)
	mv _TaskCtrlClient.so TaskCtrlClient.py ./lib

TaskCtrlServer: lib $(TASKCTRLCLIENT_OBJECTS)
	swig $(INCLUDES) -c++ -python -o TaskCtrlServer_Python.cpp \
		$(MACIINTERFACEPATH)/TaskCtrl/TaskCtrlServer.i
	$(COMPILECPP) $(PYLIB) \
		TaskCtrlServer_Python.cpp -o TaskCtrlServer_Python.opp
	$(LINK) -shared -fPIC -o _TaskCtrlServer.so \
		$(TASKCTRLCLIENT_OBJECTS) $(MACIOBJSCPP) \
		TaskCtrlServer_Python.opp \
		$(LIBS) $(MACI_INTERFACE_TASKCTRL_EXT_LIBS)
	mv _TaskCtrlServer.so TaskCtrlServer.py ./lib
################################################################


###################################################
###################################################
lib:
	@mkdir -p lib
	@echo "      [MKDIR] $@"
###############################################
###############################################

.PHONY: clean maci-clean maciclean real-clean realclean
local-clean clean:
	@rm -f *.o *.opp *.dopp *.cpp $(TARGETS)
	@echo "     [LOCAL-CLEAN]"

maciclean maci-clean real-clean realclean: maciclean
	rm -f $(OBJSC) $(OBJSCPP) \
	$(COORDINATEDRIVECLIENT_OBJECTS) \
	$(RANGINGCLIENT_OBJECTS) \
	$(POSITIONCLIENT_OBJECTS) \
	$(JOINTGROUPCTRLCLIENT_OBJECTS) \
	$(IOCLIENT_OBJECTS) \
	$(IMAGECLIENT_OBJECTS) \
	$(MAPCLIENT_OBJECTS) \
	$(TASKCTRLCLIENT_OBJECTS) 
	rm -rf ./lib
	@echo "     [REAL-CLEAN]"

########### Compile rules ####################
# Compile rule for all .o (.c) file
%.o:	%.c
	@$(COMPILEC) -o $@ $<
	@echo "      [CC] $<"

# Compile rule for all .opp (.cpp) files
%.opp:	%.cpp
	@$(COMPILECPP) -o $@ $<
	@echo "      [CXX] $<"

# Compile rule for all .dopp (dirty .cpp) files
%.dopp:	%.cpp
	@$(COMPILEDCPP) -o $@ $<
	@echo "      [DIRTY-CXX] $<"

##############################################
